package top.wilsonlv.jaguar.cloud.auth.extension.sms;

import org.springframework.security.authentication.AccountStatusException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.util.StringUtils;
import top.wilsonlv.jaguar.cloud.auth.sdk.token.SmsAuthenticationToken;
import top.wilsonlv.jaguar.cloud.auth.sdk.token.SmsDTO;
import top.wilsonlv.jaguar.commons.web.util.WebUtil;

import javax.servlet.http.HttpServletRequest;

/**
 * @author lvws
 * @since 2022/3/30 0030
 */
public class SmsCodeTokenGranter extends AbstractTokenGranter {

    private static final String GRANT_TYPE = "sms_code";

    private final AuthenticationManager authenticationManager;

    private final SmsService smsService;

    public SmsCodeTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices,
                               ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, SmsService smsService) {
        super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
        this.authenticationManager = authenticationManager;
        this.smsService = smsService;
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        HttpServletRequest request = WebUtil.getRequest();
        assert request != null;

        SmsDTO smsDTO = smsService.request2DTO(request);
        if (!StringUtils.hasText(smsDTO.getPrincipal())) {
            throw new InvalidGrantException("手机号或邮箱为非空");
        }

        if (!StringUtils.hasText(smsDTO.getTicket())) {
            throw new InvalidGrantException("ticket为非空");
        }

        if (!StringUtils.hasText(smsDTO.getSmsCode())) {
            throw new InvalidGrantException("短信验证码为非空");
        }

        SmsAuthenticationToken token = new SmsAuthenticationToken(smsDTO);

        Authentication authentication;
        try {
            authentication = authenticationManager.authenticate(token);
        } catch (AccountStatusException ase) {
            throw new InvalidGrantException(ase.getMessage());
        }

        OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
        return new OAuth2Authentication(storedOAuth2Request, authentication);
    }
}
